
function WebProgressListener(/*ProgressMeter*/ progress, /*TextBox*/ urlbar, 
    /*StatusBarPanel*/ status) {
    this.progress = progress;
    this.urlbar = urlbar;
    this.status = status;
    
    this.onDocumentStop = null;
}

WebProgressListener.prototype = {
    requestsStarted: 0,
    requestsFinished: 0,
    
    QueryInterface: function(iid) {
        if (iid.equals(Components.interfaces.nsIWebProgressListener) ||
            iid.equals(Components.interfaces.nsISupportsWeakReference) ||
            iid.equals(Components.interfaces.nsISupports))
            return this;
        
        throw Components.results.NS_ERROR_NO_INTERFACE;
    },
    
    onStateChange: function(webProgress, request, stateFlags, status) {
        const WPL = Components.interfaces.nsIWebProgressListener;
        
        if (stateFlags & WPL.STATE_IS_REQUEST) {
            if (stateFlags & WPL.STATE_START) 
                this.requestsStarted++;
            else if (stateFlags & WPL.STATE_STOP) 
                this.requestsFinished++;
            
            if (this.requestsStarted > 1) {
                var percent = 100 * this.requestsFinished / this.requestsStarted;
                this.progress.setAttribute("mode", "determined");
                this.progress.setAttribute("value", percent + "%");    
            }
        }
        
        if (stateFlags & WPL.STATE_IS_NETWORK) {
            if (stateFlags & WPL.STATE_START) 
                this.progress.setAttribute("style", "");
            else if (stateFlags & WPL.STATE_STOP) {
                this.progress.setAttribute("style", "display: none");
                this.requestsStarted = this.requestsFinished = 0;
            }
        }
        
        if (stateFlags & WPL.STATE_IS_DOCUMENT) {
            if (stateFlags & WPL.STATE_STOP) {
                this.onStatusChange(webProgress, request, 0, "Ready");
                
                if (this.onDocumentStop)
                    this.onDocumentStop();
            } else if (stateFlags & WPL.STATE_START) {
                this.status.setAttribute("label", "");
            }
        }            
    },
    
    onProgressChange: function(webProgress, request, curSelf, maxSelf,
                               curTotal, maxTotal) {
        if (this.requestsStarted == 1) {
            if (maxSelf == -1) 
                this.progress.setAttribute("mode", "undetermined");
            else {
                var percent = 100 * curSelf / maxSelf;
                this.progress.setAttribute("mode", "determined");
                this.progress.setAttribute("value", percent + "%");
            }
        }
    },

    onLocationChange: function(webProgress, request, location) {
            this.urlbar.value = location.spec;
    },
    
    onStatusChange: function(webProgress, request, status, message) {
        if (this.status.getAttribute("label") != "Ready")
            this.status.setAttribute("label", message);
    },
    
    onSecurityChange: function(webProgress, request, state) {
        /* we don't need to do anything here */
    }
};